function hook_paginator() {
    var url = window.location.href;
    var paginator = $('div.paginator');

    if (paginator.length == 0) {
        console.log('missing paginator for url ' + url);
        return;
    }

    var item_selector = PAGES.find(url).items_selector;
    var items = $(item_selector);

    if (items.length == 0) {
        console.log('missing items selector ' + item_selector + ' for url ' + url);
        return;
    }

    var item_height = items.height();
    var item_container = items.parent();

    var fetching = false;

    $(document).scroll(function () {
        if (fetching) return;

        var viewport_height = $(window).height();
        var paginator_offset = paginator.offset().top - $(document).scrollTop() - viewport_height;

        if (paginator_offset < item_height * 3) {
            fetching = true;

            var link = paginator.find('span.next a');

            if (link.length) {
                var url = link.attr('href');

                paginator.append("<img src='" + chrome.extension.getURL('/assets/img/loading.gif') + "' style='width: 24px'>");

                $.get(url, null, function (html, status, xhr) {
                    fetching = false;

                    var dom = $(html);
                    var items = dom.find(item_selector);

                    item_container.append(items);

                    console.log("insert " + items.length + " items from " + url);

                    paginator.parent().append(dom.find('div.paginator'));
                    paginator.remove();

                    paginator = $('div.paginator');

                    var num = $('span.subject-num');

                    if (num.length) {
                        var total = num.text().split('/')[1];

                        num.text('1-' + $(item_selector).length + '/' + total);
                    }
                }, 'html');
            } else {
                paginator.remove();
            }
        }
    });
}

read_option('douban_auto_paginator', function (k, v) {
    if (v) hook_paginator();
});

function test_paginator()
{
    module("paginator");

    test("items selector", function() {
        equal(PAGES.home.items_selector, PAGES.find('http://www.douban.com/').items_selector);
        equal(PAGES.doulist.items_selector, PAGES.find('http://movie.douban.com/doulist/293933/').items_selector);
        equal(PAGES.photos.items_selector, PAGES.find('http://www.douban.com/people/fishbone555/photos').items_selector);
        equal(PAGES.album.items_selector, PAGES.find('http://www.douban.com/photos/album/62449594/').items_selector);
        equal(PAGES.online.items_selector, PAGES.find('http://www.douban.com/online/').items_selector);
        equal(PAGES.discussion.items_selector, PAGES.find('http://www.douban.com/group/gamemaker/discussion?start=25').items_selector);
        equal(PAGES.events.items_selector, PAGES.find('http://beijing.douban.com/events/today/salon').items_selector);
        equal(PAGES.myevents.items_selector, PAGES.find('http://www.douban.com/location/people/flier/?g=a').items_selector);
        equal(PAGES.mygroup.items_selector, PAGES.find('http://www.douban.com/group/my_topics').items_selector);
    });
}